/**
* axios.js提供request请求封装
* 包括 get、post、delete、put等方式
* @author: sgy
*/
import axios from './axios';
import store from '@/store';
import router from '@/router'
import {aes, sign} from '@/common/js/crypto';
import {RSAencrypt} from "@/common/js/encrypt"
import { Message } from 'element-ui';

const ajax = axios.create({
  // baseURL: store.getters.serviceHost, // url前缀
  baseURL: 'http://127.0.0.1',
  timeout: 10000,                     // 超时毫秒数
  withCredentials: false               // 携带认证信息cookie
});


/**
* get方式请求，url传参
* @param url 请求url
* @param params 参数
* @param level 0:无加密，1：参数加密，2: 签名+时间戳； 默认0
*/
const get = (url, params, level) => ajax(getConfig(url, 'get', true, params, level)).then(res => successback(res)).catch(error => errback(error));
/**
* post方式请求 json方式传参
* @param url 请求url
* @param params 参数
* @param level 0:无加密，1：参数加密，2: 签名+时间戳； 默认0
*/
const postJson = (url, params, level) => ajax(getConfig(url, 'post', true, params, level)).then(res => successback(res)).catch(error => errback(error));
/**
* post方式请求 表单传参
* @param url 请求url
* @param params 参数
* @param level 0:无加密，1：参数加密，2: 签名+时间戳； 默认0
*/
const post = (url, params, level) => ajax(getConfig(url, 'post', false, params, level)).then(res => successback(res)).catch(error => errback(error));
/**
* delete方式请求 url传参
* @param url 请求url
* @param params 参数
* @param level 0:无加密，1：参数加密，2: 签名+时间戳； 默认0
*/
const del = (url, params, level) => ajax(getConfig(url, 'delete', true, params, level)).then(res => successback(res)).catch(error => errback(error));
/**
* put方式请求 json传参
* @param url 请求url
* @param params 参数
* @param level 0:无加密，1：参数加密，2: 签名+时间戳； 默认0
*/
const putJson = (url, params, level) => ajax(getConfig(url, 'put', true, params, level)).then(res => successback(res)).catch(error => errback(error));
/**
* put方式请求 表单传参
* @param url 请求url
* @param params 参数
* @param level 0:无加密，1：参数加密，2: 签名+时间戳； 默认0
*/
const put = (url, params, level) => ajax(getConfig(url, 'put', false, params, level)).then(res => successback(res)).catch(error => errback(error));


// 参数转换
const param2String = data => {
  console.log('data', data);
  if (typeof data === 'string') {
    return data;
  }
  let ret = '';
  for (let it in data) {
    let val = data[it];
    if (typeof val === 'object' && //
        (!(val instanceof Array) || (val.length > 0 && (typeof val[0] === 'object')))) {
      val = JSON.stringify(val);
    }
    ret += it + '=' + encodeURIComponent(val) + '&';
  }
  if (ret.length > 0) {
    ret = ret.substring(0, ret.length - 1);
  }
  return ret;
};

/**
 * 生成随机字符串
 * @param len 指定长度
 */
const randomString = len => {
  len = len || 32;
  let $chars = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678';    /****默认去掉了容易混淆的字符oOLl,9gq,Vv,Uu,I1****/
  let maxPos = $chars.length;
  let pwd = '';
　for (let i = 0; i < len; i++) {
　　　pwd += $chars.charAt(Math.floor(Math.random() * maxPos));
　}
　return pwd;
}

// 错误回调函数
const errback = error => {
  if ('code' in error) {
    // 未登录
    if (error.code === 1005) {
      sessionStorage.clear();
      router.push({path: '/login',query: {redirect: router.currentRoute.fullPath}})
      return {};
    }
    return Promise.reject(error);
  }
  // 网络异常,或链接超时
  Message({
    message: error.message,
    type: 'error'
  });
  return Promise.reject({data: error.message});
};
// 成功回调函数
const successback = res => {
  if (res.status === 200 && res.data.code !== 200) {
      Message({
        message: res.data.message,
        type: 'error'
      });
      return Promise.reject(res.data);
  }
  return res.data;
};

/**
 * 从1970年开始的毫秒数然后截取10位变成 从1970年开始的秒数
 * @return 返回10位时间戳
 */
const timestamp = () => {
  // new Date().getTime();
  let tmp = Date.parse( new Date() ).toString();
  tmp = tmp.substr(0,10);
  return tmp;
}

/**
* @param url 请求url
* @param method get,post,put,delete
* @param isjson 是否json提交参数
* @param params 参数
* @param level 0:无加密，1：参数加密，2: 签名+时间戳； 默认0
* 签名格式 data(字典升序) + token + key(随机生成的秘钥) + ts(当前时间戳timestamp) + nonce(随机数)
*/
const getConfig = (url, method, isjson, params, level = 0) => {
  let config_ = {
    url,
    method,
    // params, data,
    headers: {
      level
    }
  };
  // 获取token
  let token = store.state.token;
  if (!token) {
    let user = sessionStorage.getItem('user')
    token = user == null ? '' : JSON.parse(user).token;
    store.state.token = token;
  }
  
  // 时间戳
  if (level === 1) { // 加密
    params = {encrypt: RSAencrypt(JSON.stringify(params))};
    config_.headers = {
      level,
      token,
   };
  } else if (level === 2) { // 签名
    let ts = timestamp()
    // 签名key
    let key = randomString(16);
    // 加密后的签名key
    let keyEncrypt = RSAencrypt(key)
    // 随机字符串
    let nonce = randomString(10)
    // 签名串
    let signstr = sign(token, ts , params , key , nonce);
    console.log("params",params);
    console.log('token', token);
    console.log('sign', signstr);
    console.log('nonce',nonce);
    console.log('ts',ts);
    config_.headers = {
       level,
       ts,
       sign: signstr,
       token,
       nonce,
       key: keyEncrypt
    };
  }
   // 表单提交参数
  if (!isjson) {
    config_.headers['Content-Type'] = 'application/x-www-form-urlencoded';
    config_.responseType = 'text';
    config_.transformRequest = [function (data) {
      return param2String(data);
   }];
  }
  // 设置参数
  if (method in {'get': true, 'delete': true}) {
    config_.params = params;
  } else if (method in {'post': true, 'put': true}) {
    config_.data = params;
  }
  return config_;
};

// 统一方法输出口
export {
  ajax,
  get,
  postJson,
  post,
  del,
  putJson,
  put
};